'use client';

import styled from '@emotion/styled';
import { ErrorBoundary } from '@sentry/nextjs';
import { useStatsigClient } from '@statsig/react-bindings';
import { createSyncStoragePersister } from '@tanstack/query-sync-storage-persister';
import { PersistQueryClientProvider } from '@tanstack/react-query-persist-client';
import { observer } from 'mobx-react-lite';
import { useParams, useSearchParams } from 'next/navigation';
import { lazy, useEffect, useRef, useState } from 'react';

import { useStores } from '@/app/(root)/AppProviders';
import LazyLoadedModal from '@/components/modal/LazyLoadedModal';
import { ModalTypes } from '@/components/modal/constants/ModalTypes';
import SideNav from '@/components/section/SideNav';
import { DSPModuleContextProvider } from '@/components/studio/DSPModuleContext';
import DelayedLegacyEditButton from '@/components/studio/DelayedLegacyEditButton';
import { StudioContextProvider } from '@/components/studio/StudioContext';
import StudioLayoutV1 from '@/components/studio/StudioLayoutV1';
import {
  StudioProjectManagementContext,
  useStudioProjectManagement,
} from '@/components/studio/StudioProjectManagementContext';
import queryClient from '@/components/studio/queryClient';
import { StudioProjectState } from '@/components/studio/types';
import { AlternateControllerContextProvider } from '@/components/studio/useAlternateController';
import { PlanFeature } from '@/state/sessionStore';
import { isFeatureEnabledForPlan } from '@/utils/session';

import StemSplitContext, {
  useStemSplitContext,
} from '../../stems/StemSplitContext';
import WelcomeEditModal from '../../stems/WelcomeEditModal';

const StemsModal = lazy(() => import('@/app/(root)/stems/StemsModal'));

const hasLocalStorage = typeof localStorage !== 'undefined';

const persister = createSyncStoragePersister({
  storage: hasLocalStorage ? localStorage : undefined,
});

const Wrapper = styled.div`
  position: fixed;
  top: 0;
  left: 66px;
  right: 0;
  bottom: 0;
  background-color: #000;
`;

export default observer(function EditV3Client() {
  const { slug } = useParams();
  const { playbar, session } = useStores();
  const statsigClient = useStatsigClient();

  useEffect(() => {
    playbar.unsetClip();
  }, [playbar.clip, playbar.unsetClip]);

  useEffect(() => {
    document.body.style.overscrollBehaviorX = 'contain';
    document.body.parentElement!.style.overscrollBehaviorX = 'contain';

    return () => {
      document.body.style.overscrollBehaviorX = '';
      document.body.parentElement!.style.overscrollBehaviorX = '';
    };
  });

  const [loadedProject, setLoadedProject] = useState<{
    title: string;
    state: StudioProjectState;
    id: string;
  } | null>(null);

  const studioProjectManagement = useStudioProjectManagement(
    loadedProject,
    setLoadedProject
  );

  const hasInitializedRef = useRef(false);
  useEffect(() => {
    if (hasInitializedRef.current) return;
    if (
      !studioProjectManagement.loadedProject &&
      !studioProjectManagement.isLoading
    ) {
      studioProjectManagement.createOrLoadEditProject(slug as string);
      hasInitializedRef.current = true;
    }
  }, [
    !studioProjectManagement.loadedProject,
    studioProjectManagement.isLoading,
    studioProjectManagement.createOrLoadEditProject,
    slug,
  ]);

  const stemSplitContext = useStemSplitContext();

  const queryParams = useSearchParams();

  useEffect(() => {
    if (queryParams.get('stems') && !!slug) {
      stemSplitContext.setSplittingClipId(slug as string);
    }
  }, [queryParams]);

  const [showWelcomeModal, setShowWelcomeModal] = useState<boolean>(false);

  // Update global welcome modal state when local state changes
  useEffect(() => {
    session.setWelcomeModalOpen(showWelcomeModal);
  }, [showWelcomeModal, session]);

  useEffect(() => {
    if (!hasLocalStorage) return;
    const seen = localStorage.getItem('editv3-welcome-modal-seen');
    if (!seen && statsigClient.checkGate('new-user-welcome-onboarding')) {
      setShowWelcomeModal(true);
    }
  }, [statsigClient]);

  const handleCloseWelcomeModal = () => {
    if (hasLocalStorage) {
      localStorage.setItem('editv3-welcome-modal-seen', 'true');
    }
    setShowWelcomeModal(false);
  };

  if (!studioProjectManagement.loadedProject) {
    return (
      <div className='flex h-full w-full flex-col items-center justify-center'>
        Loading Edit Session...
        {slug && <DelayedLegacyEditButton clipId={slug as string} />}
      </div>
    );
  }

  return (
    <ErrorBoundary
      fallback={({ error }) => (
        <div className='flex h-full w-full flex-col items-center justify-center'>
          An error occured.{' '}
          {slug ? (
            <>
              Please try again, or click the button below to open in the legacy
              editor.{' '}
              <DelayedLegacyEditButton clipId={slug as string} delayTime={0} />
            </>
          ) : (
            <>Please try again later.</>
          )}
          <pre className='mt-8 max-h-[50vh] min-h-[200px] max-w-full min-w-[300px] overflow-y-auto rounded-md bg-gray-100 p-2 text-xs whitespace-pre-wrap text-[#444]'>
            ERROR INFO:{'\n\n'}
            Message: {(error as any)?.message ?? '[No Error Message]'}
          </pre>
        </div>
      )}
    >
      <PersistQueryClientProvider
        client={queryClient}
        persistOptions={{ persister }}
      >
        <StudioProjectManagementContext.Provider
          value={studioProjectManagement}
        >
          <StemSplitContext.Provider value={stemSplitContext}>
            <DSPModuleContextProvider editModeClipId={slug as string}>
              {showWelcomeModal && (
                <WelcomeEditModal onClose={handleCloseWelcomeModal} />
              )}
              {isFeatureEnabledForPlan(session, PlanFeature.GetStems) &&
                stemSplitContext.splittingClipId && (
                  <LazyLoadedModal
                    modalType={ModalTypes.STEMS}
                    Component={StemsModal}
                    // need to pass in isOpen explicitly here because this is using the stemSplitContext instead of the ModalContext for open / closing
                    isOpen={!!stemSplitContext.splittingClipId}
                    clipId={stemSplitContext.splittingClipId}
                    onClose={() => {
                      stemSplitContext.setSplittingClipId(null);
                    }}
                  />
                )}
              <StudioContextProvider
                studioProject={studioProjectManagement.loadedProject}
                mode='edit'
              >
                <AlternateControllerContextProvider>
                  <SideNav
                    mountCollapsed={true}
                    collapsible={true}
                    className='fixed top-0 bottom-0 left-0 z-50'
                  />
                  <Wrapper>
                    <StudioLayoutV1 />
                  </Wrapper>
                </AlternateControllerContextProvider>
              </StudioContextProvider>
            </DSPModuleContextProvider>
          </StemSplitContext.Provider>
        </StudioProjectManagementContext.Provider>
      </PersistQueryClientProvider>
    </ErrorBoundary>
  );
});
